home *** CD-ROM | disk | FTP | other *** search
/ Mac Easy 2010 May / Mac Life Ubuntu.iso / casper / filesystem.squashfs / usr / share / python-support / python-rdflib / rdflib / sparql / QueryResult.py < prev    next >
Encoding:
Python Source  |  2007-04-04  |  14.2 KB  |  329 lines

  1. from rdflib import QueryResult,URIRef,BNode,Literal, Namespace
  2. from xml.dom import XML_NAMESPACE
  3. from xml.sax.saxutils import XMLGenerator
  4. from xml.sax.xmlreader import AttributesNSImpl
  5. from cStringIO import StringIO
  6.  
  7. SPARQL_XML_NAMESPACE = u'http://www.w3.org/2005/sparql-results#'
  8.  
  9. try:
  10.     from Ft.Xml import MarkupWriter
  11.     class SPARQLXMLWriter:
  12.         """
  13.         4Suite-based SPARQL XML Writer
  14.         """
  15.         def __init__(self,output):
  16.             self.writer = MarkupWriter(output, indent=u"yes")
  17.             self.writer.startDocument()
  18.             self.writer.startElement(u'sparql',namespace=SPARQL_XML_NAMESPACE)
  19.  
  20.         def write_header(self,allvarsL):
  21.             self.writer.startElement(u'head', namespace=SPARQL_XML_NAMESPACE)
  22.             for i in xrange(0,len(allvarsL)) :
  23.                 self.writer.startElement(u'variable',namespace=SPARQL_XML_NAMESPACE,attributes={u'name':unicode(allvarsL[i][1:])})
  24.                 self.writer.endElement(u'variable')
  25.             self.writer.endElement( u'head')
  26.  
  27.         def write_results_header(self,orderBy,distinct):
  28.             self.writer.startElement(u'results',namespace=SPARQL_XML_NAMESPACE,attributes={u'ordered' : unicode(orderBy and 'true' or 'false'),
  29.                                                                                            u'distinct': unicode(distinct and 'true' or 'false')})
  30.  
  31.         def write_start_result(self):
  32.             self.writer.startElement(u'result',namespace=SPARQL_XML_NAMESPACE)
  33.             self._resultStarted = True
  34.  
  35.         def write_end_result(self):
  36.             assert self._resultStarted
  37.             self.writer.endElement(u'result',namespace=SPARQL_XML_NAMESPACE)
  38.             self._resultStarted = False
  39.  
  40.         def write_binding(self,name,val):
  41.             assert self._resultStarted
  42.             if val:
  43.                 attrs = {u'name':unicode(name)}
  44.                 self.writer.startElement(u'binding', namespace=SPARQL_XML_NAMESPACE, attributes=attrs)
  45.                 if isinstance(val,URIRef) :
  46.                     self.writer.startElement(u'uri', namespace=SPARQL_XML_NAMESPACE)
  47.                     self.writer.text(val)
  48.                     self.writer.endElement(u'uri')
  49.                 elif isinstance(val,BNode) :
  50.                     self.writer.startElement(u'bnode', namespace=SPARQL_XML_NAMESPACE)
  51.                     self.writer.text(val)
  52.                     self.writer.endElement(u'bnode')
  53.                 elif isinstance(val,Literal) :
  54.                     attrs = {}
  55.                     if val.language :
  56.                         attrs[(u'lang', XML_NAMESPACE)] = unicode(val.language)
  57.                     elif val.datatype:
  58.                         attrs[u'datatype'] = unicode(val.datatype)
  59.                     self.writer.startElement(u'literal', namespace=SPARQL_XML_NAMESPACE, attributes=attrs)
  60.                     self.writer.text(val)
  61.                     self.writer.endElement(u'literal')
  62.  
  63.                 else:
  64.                     raise Exception("Unsupported RDF term: %s"%val)
  65.  
  66.                 self.writer.endElement(u'binding')
  67.  
  68.         def close(self):
  69.             self.writer.endElement(u'results')
  70.             self.writer.endElement(u'sparql')
  71. except:
  72.     class SPARQLXMLWriter:
  73.         """
  74.         Python saxutils-based SPARQL XML Writer
  75.         """
  76.         def __init__(self, output, encoding='utf-8'):
  77.             writer = XMLGenerator(output, encoding)
  78.             writer.startDocument()
  79.             writer.startPrefixMapping(u'sparql',SPARQL_XML_NAMESPACE)
  80.             writer.startPrefixMapping(u'xml', XML_NAMESPACE)
  81.             writer.startElementNS((SPARQL_XML_NAMESPACE, u'sparql'), u'sparql', AttributesNSImpl({}, {}))
  82.             self.writer = writer
  83.             self._output = output
  84.             self._encoding = encoding
  85.  
  86.         def write_header(self,allvarsL):
  87.             self.writer.startElementNS((SPARQL_XML_NAMESPACE, u'head'), u'head', AttributesNSImpl({}, {}))
  88.             for i in xrange(0,len(allvarsL)) :
  89.                 attr_vals = {
  90.                     (None, u'name'): unicode(allvarsL[i][1:]),
  91.                     }
  92.                 attr_qnames = {
  93.                     (None, u'name'): u'name',
  94.                     }
  95.                 self.writer.startElementNS((SPARQL_XML_NAMESPACE, u'variable'),
  96.                                              u'variable',
  97.                                              AttributesNSImpl(attr_vals, attr_qnames))
  98.                 self.writer.endElementNS((SPARQL_XML_NAMESPACE, u'variable'), u'variable')
  99.             self.writer.endElementNS((SPARQL_XML_NAMESPACE, u'head'), u'head')
  100.  
  101.         def write_results_header(self,orderBy,distinct):
  102.             attr_vals = {
  103.                 (None, u'ordered')  : unicode(orderBy and 'true' or 'false'),
  104.                 (None, u'distinct') : unicode(distinct and 'true' or 'false'),
  105.                 }
  106.             attr_qnames = {
  107.                 (None, u'ordered')  : u'ordered',
  108.                 (None, u'distinct') : u'distinct'
  109.                 }
  110.             self.writer.startElementNS((SPARQL_XML_NAMESPACE, u'results'),
  111.                                          u'results',
  112.                                          AttributesNSImpl(attr_vals, attr_qnames))
  113.  
  114.         def write_start_result(self):
  115.             self.writer.startElementNS(
  116.                     (SPARQL_XML_NAMESPACE, u'result'), u'result', AttributesNSImpl({}, {}))
  117.             self._resultStarted = True
  118.  
  119.         def write_end_result(self):
  120.             assert self._resultStarted
  121.             self.writer.endElementNS((SPARQL_XML_NAMESPACE, u'result'), u'result')
  122.             self._resultStarted = False
  123.  
  124.         def write_binding(self,name,val):
  125.             assert self._resultStarted
  126.             if val:
  127.                 attr_vals = {
  128.                     (None, u'name')  : unicode(name),
  129.                     }
  130.                 attr_qnames = {
  131.                     (None, u'name')  : u'name',
  132.                     }
  133.                 self.writer.startElementNS((SPARQL_XML_NAMESPACE, u'binding'),
  134.                                        u'binding',
  135.                                        AttributesNSImpl(attr_vals, attr_qnames))
  136.  
  137.                 if isinstance(val,URIRef) :
  138.                     self.writer.startElementNS((SPARQL_XML_NAMESPACE, u'uri'),
  139.                                            u'uri',
  140.                                            AttributesNSImpl({}, {}))
  141.                     self.writer.characters(val)
  142.                     self.writer.endElementNS((SPARQL_XML_NAMESPACE, u'uri'),u'uri')
  143.                 elif isinstance(val,BNode) :
  144.                     self.writer.startElementNS((SPARQL_XML_NAMESPACE, u'bnode'),
  145.                                            u'bnode',
  146.                                            AttributesNSImpl({}, {}))
  147.                     self.writer.characters(val)
  148.                     self.writer.endElementNS((SPARQL_XML_NAMESPACE, u'bnode'),u'bnode')
  149.                 elif isinstance(val,Literal) :
  150.                     attr_vals = {}
  151.                     attr_qnames = {}
  152.                     if val.language :
  153.                         attr_vals[(XML_NAMESPACE, u'lang')] = val.language
  154.                         attr_qnames[(XML_NAMESPACE, u'lang')] = u"xml:lang"
  155.                     elif val.datatype:
  156.                         attr_vals[(None,u'datatype')] = val.datatype
  157.                         attr_qnames[(None,u'datatype')] = u'datatype'
  158.  
  159.                     self.writer.startElementNS((SPARQL_XML_NAMESPACE, u'literal'),
  160.                                            u'literal',
  161.                                            AttributesNSImpl(attr_vals, attr_qnames))
  162.                     self.writer.characters(val)
  163.                     self.writer.endElementNS((SPARQL_XML_NAMESPACE, u'literal'),u'literal')
  164.  
  165.                 else:
  166.                     raise Exception("Unsupported RDF term: %s"%val)
  167.  
  168.                 self.writer.endElementNS((SPARQL_XML_NAMESPACE, u'binding'),u'binding')
  169.  
  170.         def close(self):
  171.             self.writer.endElementNS((SPARQL_XML_NAMESPACE, u'results'), u'results')
  172.             self.writer.endElementNS((SPARQL_XML_NAMESPACE, u'sparql'), u'sparql')
  173.             self.writer.endDocument()
  174.  
  175. def retToJSON(val):
  176.     if isinstance(val,URIRef):
  177.         return '"type": "uri", "value" : "%s"' % val
  178.     elif isinstance(val,BNode) :
  179.         return '"type": "bnode", "value" : "%s"' % val
  180.     elif isinstance(val,Literal):
  181.         if val.language != "":
  182.             return '"type": "literal", "xml:lang" : "%s", "value" : "%s"' % (val.language, val)
  183.             attr += ' xml:lang="%s" ' % val.language
  184.         elif val.datatype != "" and val.datatype != None:
  185.             return '"type": "typed=literal", "datatype" : "%s", "value" : "%s"' % (val.datatype, val)
  186.         else:
  187.             return '"type": "literal", "value" : "%s"' % val
  188.     else:
  189.         return '"type": "literal", "value" : "%s"' % val
  190.  
  191. def bindingJSON(name, val):
  192.     if val == None:
  193.         return ""
  194.     retval = ''
  195.     retval += '                   "%s" : {' % name
  196.     retval += retToJSON(val)
  197. #    retval += '}\n'
  198.     return retval
  199.  
  200. class SPARQLQueryResult(QueryResult.QueryResult):
  201.     """
  202.     Query result class for SPARQL
  203.  
  204.     xml   : as an XML string conforming to the SPARQL XML result format: http://www.w3.org/TR/rdf-sparql-XMLres/
  205.     python: as Python objects
  206.     json  : as JSON
  207.     graph : as an RDFLib Graph - for CONSTRUCT and DESCRIBE queries
  208.     """
  209.     def __init__(self,qResult):
  210.         """
  211.         The constructor is the result straight from sparql-p, which is uple of 1) a list of tuples
  212.         (in select order, each item is the valid binding for the corresponding variable or 'None') for SELECTs
  213.         , a SPARQLGraph for DESCRIBE/CONSTRUCT, and boolean for ASK  2) the variables selected 3) *all*
  214.         the variables in the Graph Patterns 4) the order clause 5) the DISTINCT clause
  215.         """
  216.         result,selectionF,allVars,orderBy,distinct = qResult
  217.         self.selected = result
  218.         self.selectionF = selectionF
  219.         self.allVariables = allVars
  220.         self.orderBy = orderBy
  221.         self.distinct = distinct
  222.  
  223.     def __len__(self):
  224.         if isinstance(self.selected,list):
  225.             return len(self.selected)
  226.         else:
  227.             return 1
  228.  
  229.     def __iter__(self):
  230.         """Iterates over the result entries"""
  231.         if isinstance(self.selected,list):
  232.             for item in self.selected:
  233.                 if isinstance(item,basestring):
  234.                     yield (item,)
  235.                 else:
  236.                     yield item
  237.         else:
  238.             yield self.selected
  239.  
  240.     def serialize(self,format='xml'):
  241.         if format == 'python':
  242.             return self.selected
  243.         elif format in ['json','xml']:
  244.            retval = ""
  245.            allvarsL = self.allVariables
  246.            if format == "json" :
  247.                retval += '    "results" : {\n'
  248.                retval += '          "ordered" : %s,\n' % (self.orderBy and 'true' or 'false')
  249.                retval += '          "distinct" : %s,\n' % (self.distinct and 'true' or 'false')
  250.                retval += '          "bindings" : [\n'
  251.                for i in xrange(0,len(self.selected)):
  252.                    hit = self.selected[i]
  253.                    retval += '               {\n'
  254.                    bindings = []
  255.                    if len(self.selectionF) == 0:
  256.                         for j in xrange(0, len(allvarsL)):
  257.                             b = bindingJSON(allvarsL[j][1:],hit[j])
  258.                             if b != "":
  259.                                 bindings.append(b)
  260.                    elif len(self.selectionF) == 1:
  261.                        bindings.append(bindingJSON(self.selectionF[0][1:],hit))
  262.                    else:
  263.                         for j in xrange(0, len(self.selectionF)):
  264.                             b = bindingJSON(self.selectionF[j][1:],hit[j])
  265.                             if b != "":
  266.                                 bindings.append(b)
  267.                            
  268.                    retval += "},\n".join(bindings)
  269.                    retval += "}\n"
  270.                    retval += '                }'
  271.                    if i != len(self.selected) -1:
  272.                        retval += ',\n'
  273.                    else:
  274.                        retval += '\n'
  275.                retval += '           ]\n'
  276.                retval += '    }\n'
  277.                retval += '}\n'
  278.                
  279.                selected_vars = self.selectionF
  280.                
  281.                if len(selected_vars) == 0:
  282.                    selected_vars = allvarsL
  283.                    
  284.                header = ""
  285.                header += '{\n'
  286.                header += '   "head" : {\n        "vars" : [\n'
  287.                for i in xrange(0,len(selected_vars)) :
  288.                    header += '             "%s"' % selected_vars[i][1:]
  289.                    if i == len(selected_vars) - 1 :
  290.                        header += '\n'
  291.                    else :
  292.                        header += ',\n'
  293.                header += '         ]\n'
  294.                header += '    },\n'
  295.                
  296.                retval = header + retval
  297.                
  298.            elif format == "xml" :
  299.                # xml output
  300.                out = StringIO()
  301.                writer = SPARQLXMLWriter(out)
  302.                writer.write_header(allvarsL)
  303.                writer.write_results_header(self.orderBy,self.distinct)
  304.                for i in xrange(0,len(self.selected)) :
  305.                    hit = self.selected[i]
  306.                    if len(self.selectionF) == 0 :
  307.                        writer.write_start_result()
  308.                        if len(allvarsL) == 1:
  309.                            hit = (hit,) # Not an iterable - a parser bug?
  310.                        for j in xrange(0,len(allvarsL)) :
  311.                            writer.write_binding(allvarsL[j][1:],hit[j])
  312.                        writer.write_end_result()
  313.                    elif len(self.selectionF) == 1 :
  314.                        writer.write_start_result()
  315.                        writer.write_binding(self.selectionF[0][1:],hit)
  316.                        writer.write_end_result()
  317.                    else:
  318.                        writer.write_start_result()
  319.                        for j in xrange(0,len(self.selectionF)) :
  320.                            writer.write_binding(self.selectionF[j][1:],hit[j])
  321.                        writer.write_end_result()
  322.                writer.close()
  323.                return out.getvalue()
  324.  
  325.            return retval
  326.         else:
  327.            raise Exception("Result format not implemented: %s"%format)
  328.  
  329.